home *** CD-ROM | disk | FTP | other *** search
-
- // Matv - A Simple Matrix Class
-
- // Version: 1.0
- // Author: Mark Von Tress, Ph.D.
- // Date: 10/11/92
-
- // Copyright(c) Mark Von Tress 1992
-
-
- // DISCLAIMER: THIS PROGRAM IS PROVIDED AS IS, WITHOUT ANY
- // WARRANTY, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
- // TO FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR DISCLAIMS
- // ALL LIABILITY FOR DIRECT OR CONSEQUENTIAL DAMAGES RESULTING
- // FROM USE OF THIS PROGRAM.
-
- // test driver
-
- #include "matv.h"
-
- void foo(Matrix &arg)
- {
- static int j = 0;
- static Matrix zz = Fill(2, 2, 1);
- // call zz.CannotAlias() to protect the storage in a
- // static matrix.
- zz.CannotAlias();
- if (j < 2) cout << zz;
- if (!j++) {
- // test for side effects in reference matrices
- cout << arg;
- Matrix local(arg);
- cout << local;
- arg(1, 1) = 2000;
- cout << local;
- }
- }
-
- #define bigg 25
- // run this 1000 times. Should bomb if there is a leak.
- Matrix TestForLeak(void)
- {
- Matrix x = Inv(Fill(bigg, bigg, 1) +Ident(bigg));
- foo(Fill(2, 2, 2));
- // still works if you omit this call, but this is faster
- x.release();
- return x;
- }
- #undef bigg
-
- void TestReg()
- {
- // do regression with normal equations or g2sweep
- // read data
- Matrix xy = Reada("catchv.dat");
- xy.show("catchv.dat");
-
- // use normal equations
- Matrix x = Submat(xy, 1, 2, xy.r, 3);
- Matrix y = Submat(xy, 1, xy.c, xy.r, xy.c);
- Matrix beta = Inv(Tran(x) *x) *Tran(x) *y;
- beta.show("beta");
-
- // use sweep
- Matrix xyp = Submat(xy, 1, 2, xy.r, xy.c);
- Matrix xypxy = Tran(xyp) *xyp;
- Matrix reg_comps = Sweep(1, xyp.c - 1, xypxy);
- cout << reg_comps;
-
- beta = Submat(reg_comps, 1, reg_comps.c, reg_comps.r - 1, reg_comps.c);
- beta.show("sweep beta");
- float mse = reg_comps(reg_comps.r, reg_comps.c) / ((float) (xy.r - x.c));
- cout << "mse: " << mse << "\n";
-
- }
-
- void TestArithOperators(void)
- {
- Matrix a = Fill(5, 5, 0.5);
- Matrix b = Fill(5, 5, 2);
-
- cout << "a+b\n" << (a + b);
- cout << "a+5\n" << (a + 5);
- cout << "5+a\n" << (5 + a);
- cout << "a-b\n" << (a - b);
- cout << "a-5\n" << (a - 5);
- cout << "5-a\n" << (5 - a);
- cout << "-a\n" << - a;
- cout << "a*b\n" << a*b;
- cout << "a*5\n" << a*5;
- cout << "5*a\n" << 5*a;
- cout << "a%b\n" << a % b;
- cout << "a%5\n" << a % 5;
- cout << "5%a\n" << 5 % a;
- cout << "a/b\n" << a / b;
- cout << "a/5\n" << a / 5;
- cout << "5/a\n" << 5 / a;
- }
-
- void TestArithAssignments(void)
- {
- Matrix a = Fill(5, 5, 0.5);
- Matrix b = Fill(5, 5, 2);
- Matrix t = a;
- a += b;
- cout << "a+=b\n" << a;
- a += 5;
- cout << "a+=5\n" << a;
- a = t;
-
- a -= b;
- cout << "a-=b\n" << a;
- a -= 5;
- cout << "a-=5\n" << a;
- a = t;
-
- a *= b;
- cout << "a*=b\n" << a;
- a *= 5;
- cout << "a*=5\n" << a;
- a = t;
-
- a %= b;
- cout << "a%=b\n" << a;
- a %= 5;
- cout << "a%=5\n" << a;
- a = t;
-
- a /= b;
- cout << "a/=b\n" << a;
- a /= 5;
- cout << "a/=5\n" << a;
- a = t;
- t = a += b;
- cout << "addition then assignment" << t;
-
- Matrix k = Fill(5,3,5);
- t = Fill( 5, 5, 0.5 );
- a = t;
- t = a *= k;
- cout << "multiplication then assignment" << t;
- }
-
- /////////////////////////////////////////////////////
- //
- // The next section demonstrates a problem that
- // occurs with aliasing. If you return a matrix
- // that was passed as a reference, and you release
- // the deletion responsibility, then it will be
- // garbage later. You trip the garbage flag when you try
- // to use it after the matrix newley responsible
- // for deleting the aliased storage has actually
- // deleted the storage. The heap is notified of
- // the deletion so this problem can be detected.
- // see SetupVectors(), PurgeVectors(), and Garbage().
- //
- ////////////////////////////////////////////////////
-
- Matrix passRef(Matrix &a)
- {
- // release sets CanDelete to FFALSE, and the
- // return value gets responsibility for deleting
- // the storage in a.
- a.release();
- return a;
- }
-
- void DontDoThis(Matrix &a)
- {
- // alias problem since release() passed deletion
- // responsibility to AliasProblem. Note that
- // AliasProblem vanishes at the function exit
- // so the storage in a is now garbage!
- // To prevent this problem call a.CannotAlias(), before
- // entering this function. Or, do not release deletion
- // responsibility for matrices that are passed in as
- // references and returned at the end of a function.
- Matrix AliasProblem = passRef(a);
- }
-
- //////////////////////////////////////////////////////////////
-
- main()
- {
- ios::sync_with_stdio(); // Uncomment for SC++ Winc applications
- Matrix xt;
- for (int m = 0; m < 10; m++) {
- xt = TestForLeak();
- cout << m << " ";
- }
- cout << "\n";
-
- Matrix t(2, 2);
- cout << t;
- Matrix x = t;
- cout << x;
- x = Fill(3, 2, 1);
- cout << x;
- t = x;
- cout << t;
- t = x = Fill(3, 3, 3);
- cout << x;
- cout << t;
-
- // make a matrix from an array
- float xx[6] = {0, 1, 2, 3, 4, 5};
- Vector zz(6,xx);
- cout << "zz\n" << zz;
- t = Matrix( 2, 3, xx);
- cout << "t\n" << t;
-
- // test array of matrices
- int i, n = 5;
- Matrix *c = new Matrix[n];
- for (i = 0; i < n; i++) c[i] = Fill(i + 1, i + 1, (float) i);
- for (i = 0; i < n; i++) cout << c[i];
-
- TestReg();
- TestArithOperators();
- TestArithAssignments();
-
- // test matrix write
- cout << Inv(Ident(5) + Fill(5, 5, 1));
- Writea("junk.mat", Inv(Ident(5) + Fill(5, 5, 1)));
-
- Matrix a = Fill(5, 5, 1);
- // Uncomment the next line to prevent the alias problem in DontDoThis( a )
- // a.CannotAlias();
- DontDoThis(a);
- a.Garbage("alias problem");
-
- return 0;
- }
-